using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using NBusiness.CodeDom;

namespace NBusiness.Utilities
{
    public class Reflection
    {
        public static Type LoadType(string AssemblyName, string TypeName)
        {
            Assembly a = Assembly.Load(AssemblyName);
            Type t = a.GetType(TypeName);
            return t;
        }
        public static bool TryLoadType(string AssemblyName, string TypeName, out Type t)
        {
            bool ok = true;
            t = null;

            try
            {
                t = LoadType(AssemblyName, TypeName);
            }
            catch
            {
                ok = false;
            }

            return ok && (t != null);
        }

        public static Type[] FindTypes(Type baseType, Assembly[] assemblies, params EntityUsing[] namespaces)
        {
            List<Type> found = new List<Type>();            
            foreach (Assembly a in assemblies)
            {
                try
                {
                    foreach (Type t in a.GetTypes())
                    {
                        if (baseType.IsAssignableFrom(t) && baseType != t)
                        {

                            if (namespaces != null &&
                                namespaces.Length > 0 &&
                                new List<EntityUsing>(namespaces).Exists(
                                new Predicate<EntityUsing>(
                                delegate(EntityUsing @using)
                                {
                                    return @using.Namespace == t.Namespace;
                                }
                                )))
                            {
                                found.Add(t);
                            }
                            else if (namespaces == null || namespaces.Length < 1)
                            {
                                found.Add(t);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex, "Find Types");
                }
            }
            return found.ToArray();
        }
    }
}
